package com.bj58.mis.apm.server.kylin.common.hllc;

import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Serializable;
import java.io.Writer;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.InvalidPropertiesFormatException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.Vector;
import java.util.Map.Entry;

public final class OrderedProperties implements Serializable {
    private static final long serialVersionUID = 1L;
    private transient Map<String, String> properties;

    public OrderedProperties() {
        this(new LinkedHashMap());
    }

    public OrderedProperties(Map<String, String> properties) {
        this.properties = properties;
    }

    public static OrderedProperties copyOf(OrderedProperties source) {
        OrderedProperties.OrderedPropertiesBuilder builder = new OrderedProperties.OrderedPropertiesBuilder();
        if (source.properties instanceof TreeMap) {
            builder.withOrdering(((TreeMap)source.properties).comparator());
        }

        OrderedProperties result = builder.build();
        Iterator i$ = source.entrySet().iterator();

        while(i$.hasNext()) {
            Entry<String, String> entry = (Entry)i$.next();
            result.setProperty((String)entry.getKey(), (String)entry.getValue());
        }

        return result;
    }

    public String getProperty(String key) {
        return (String)this.properties.get(key);
    }

    public String getProperty(String key, String defaultValue) {
        String value = (String)this.properties.get(key);
        return value == null ? defaultValue : value;
    }

    public String setProperty(String key, String value) {
        return (String)this.properties.put(key, value);
    }

    public String removeProperty(String key) {
        return (String)this.properties.remove(key);
    }

    public boolean containsProperty(String key) {
        return this.properties.containsKey(key);
    }

    public int size() {
        return this.properties.size();
    }

    public boolean isEmpty() {
        return this.properties.isEmpty();
    }

    public Enumeration<String> propertyNames() {
        return (new Vector(this.properties.keySet())).elements();
    }

    public Set<String> stringPropertyNames() {
        return new LinkedHashSet(this.properties.keySet());
    }

    public Set<Entry<String, String>> entrySet() {
        return new LinkedHashSet(this.properties.entrySet());
    }

    public void putAll(OrderedProperties others) {
        Iterator i$ = others.entrySet().iterator();

        while(i$.hasNext()) {
            Entry<String, String> each = (Entry)i$.next();
            this.properties.put(each.getKey(), each.getValue());
        }

    }

    public void load(InputStream stream) throws IOException {
        OrderedProperties.CustomProperties customProperties = new OrderedProperties.CustomProperties(this.properties);
        customProperties.load(stream);
    }

    public void load(Reader reader) throws IOException {
        OrderedProperties.CustomProperties customProperties = new OrderedProperties.CustomProperties(this.properties);
        customProperties.load(reader);
    }

    public void loadFromXML(InputStream stream) throws IOException, InvalidPropertiesFormatException {
        OrderedProperties.CustomProperties customProperties = new OrderedProperties.CustomProperties(this.properties);
        customProperties.loadFromXML(stream);
    }

    public void store(OutputStream stream, String comments) throws IOException {
        OrderedProperties.CustomProperties customProperties = new OrderedProperties.CustomProperties(this.properties);
        customProperties.store(stream, comments);
    }

    public void store(Writer writer, String comments) throws IOException {
        OrderedProperties.CustomProperties customProperties = new OrderedProperties.CustomProperties(this.properties);
        customProperties.store(writer, comments);
    }

    public void storeToXML(OutputStream stream, String comment) throws IOException {
        OrderedProperties.CustomProperties customProperties = new OrderedProperties.CustomProperties(this.properties);
        customProperties.storeToXML(stream, comment);
    }

    public void storeToXML(OutputStream stream, String comment, String encoding) throws IOException {
        OrderedProperties.CustomProperties customProperties = new OrderedProperties.CustomProperties(this.properties);
        customProperties.storeToXML(stream, comment, encoding);
    }

    public void list(PrintStream stream) {
        OrderedProperties.CustomProperties customProperties = new OrderedProperties.CustomProperties(this.properties);
        customProperties.list(stream);
    }

    public void list(PrintWriter writer) {
        OrderedProperties.CustomProperties customProperties = new OrderedProperties.CustomProperties(this.properties);
        customProperties.list(writer);
    }

    public Properties toJdkProperties() {
        Properties jdkProperties = new Properties();
        Iterator i$ = this.entrySet().iterator();

        while(i$.hasNext()) {
            Entry<String, String> entry = (Entry)i$.next();
            jdkProperties.put(entry.getKey(), entry.getValue());
        }

        return jdkProperties;
    }

    public boolean equals(Object other) {
        if (this == other) {
            return true;
        } else if (other != null && this.getClass() == other.getClass()) {
            OrderedProperties that = (OrderedProperties)other;
            return Arrays.equals(this.properties.entrySet().toArray(), that.properties.entrySet().toArray());
        } else {
            return false;
        }
    }

    public int hashCode() {
        return Arrays.hashCode(this.properties.entrySet().toArray());
    }

    private void writeObject(ObjectOutputStream stream) throws IOException {
        stream.defaultWriteObject();
        stream.writeObject(this.properties);
    }

    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
        stream.defaultReadObject();
        this.properties = (Map)stream.readObject();
    }

    public String toString() {
        return this.properties.toString();
    }

    public Map<String, String> getProperties() {
        return this.properties;
    }

    private static final class CustomProperties extends Properties {
        private final Map<String, String> targetProperties;

        private CustomProperties(Map<String, String> targetProperties) {
            this.targetProperties = targetProperties;
        }

        public Object get(Object key) {
            return this.targetProperties.get(key);
        }

        public Object put(Object key, Object value) {
            return this.targetProperties.put((String)key, (String)value);
        }

        public String getProperty(String key) {
            return (String)this.targetProperties.get(key);
        }

        public Enumeration<Object> keys() {
            return (new Vector(this.targetProperties.keySet())).elements();
        }

        public Set<Object> keySet() {
            return new LinkedHashSet(this.targetProperties.keySet());
        }
    }

    public static final class OrderedPropertiesBuilder {
        private Comparator<? super String> comparator;

        public OrderedPropertiesBuilder() {
        }

        public OrderedProperties.OrderedPropertiesBuilder withOrdering(Comparator<? super String> comparator) {
            this.comparator = comparator;
            return this;
        }

        public OrderedProperties build() {
            Map<String, String> properties = this.comparator != null ? new TreeMap(this.comparator) : new LinkedHashMap();
            return new OrderedProperties((Map)properties);
        }
    }
}

